﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using AL.Common;
using AL.Entity;
using STSdb4.Database;
using System.Linq.Expressions;

namespace AL.DAL.PublicAccount
{

    /// <summary>
    /// 公众号数据操作类
    /// </summary>
    public static class Provider
    {


        private static XIndex<string, Account> _table = null;

        private static readonly string Path = Config.DataPath;
        private const string SystemFileName = "HH_Account.sys";
        private const string DataFileName = "HH_Account.dat";

        private const string DataTableName = "PublicAccount";


        // 防止文件占用
        //private static string _lockStatus = "None";
        private static bool _isWorking = false;

        /// <summary>
        /// HH: 新增一条记录
        /// </summary>
        public static string Add(Account record)
        {
            //// 如果再出问题就使用 Lock 锁
            //lock (_lockStatus) {
            //    // 需要执行的代码
            //};

            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            var openId = record.OpenId;
            if (!string.IsNullOrWhiteSpace(openId))
            {
                using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
                {
                    _table = engine.OpenXIndex<string, Account>(DataTableName);

                    if (_table != null)
                    {
                        _table[record.OpenId] = record;

                        _table.Flush();
                    }
                    engine.Commit();
                }
            }
            else
            {
                openId = string.Empty;
            }

            _isWorking = false;
            return openId;
        }


        /// <summary>
        /// HH: 编辑一条记录
        /// </summary>
        public static void Mod(Account record)
        {
            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
            {
                _table = engine.OpenXIndex<string, Account>(DataTableName);

                _table.Replace(record.OpenId, record);

                _table.Flush();
                engine.Commit();

                _isWorking = false;
            }
        }


        /// <summary>
        /// HH: 根据主键 ID 删除一条记录
        /// </summary>
        public static void Del(string openId)
        {
            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
            {
                _table = engine.OpenXIndex<string, Account>(DataTableName);
                _table.Delete(openId);
                _table.Flush();
                engine.Commit();

                _isWorking = false;
            }
        }

        

        /// <summary>
        /// HH: 删除该表所有数据
        /// </summary>
        public static void Clear()
        {
            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
            {
                _table = engine.OpenXIndex<string, Account>(DataTableName);
                _table.Clear();
                _table.Flush();
                engine.Commit();

                _isWorking = false;
            }
        }



        /// <summary>
        /// HH: 根据 ID 获取一个记录对象
        /// </summary>
        public static Account GetByOpenId(string openId)
        {
            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
            {
                _table = engine.OpenXIndex<string, Account>(DataTableName);

                _isWorking = false;
                return _table.TryGetOrDefault(openId, new Account());
            }
        }




        /// <summary>
        /// HH: 查询获取对象集合
        /// </summary>
        public static List<Account> Search(List<Func<KeyValuePair<string, Account>, bool>> predicate, int inPageIndex, int inPageSize, out int outPageCount)
        {
            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
            {
                _table = engine.OpenXIndex<string, Account>(DataTableName);

                outPageCount = 0;

                //var list = _table.Backward().Where(predicate);

                // 多条件模式
                //var list = _table.Backward().Where(o => (int)o.Value.OPType == 1);
                var list = _table.Backward();
                foreach (Func<KeyValuePair<string, Account>, bool> p in predicate)
                {
                    list = list.Where(p);
                }



                if (list != null && list.Count() > 0)
                {

                    // 分页查询
                    int pageSize = inPageSize;
                    int pageIndex = inPageIndex;
                    outPageCount = list.Count();

                    var r = new List<Account> { };

                    long rowID = 1;
                    long minID = (pageIndex - 1) * pageSize + 1;
                    long maxID = minID + pageSize - 1;

                    // 遍历
                    foreach (KeyValuePair<string, Account> item in list)
                    {
                        if (rowID >= minID && rowID <= maxID)
                        {
                            r.Add(item.Value);
                        }
                        rowID++;

                        if (rowID == maxID + 1) break;
                    }


                    //var ret = table.Backward().Where(predicate).Skip(pageSize * (pageIndex - 1)).Take(pageSize);

                    //List<OPLog> r = new List<OPLog> { };
                    //foreach (KeyValuePair<long, OPLog> item in ret) {
                    //    r.Add(item.Value);
                    //}

                    _isWorking = false;
                    return r;
                }

                _isWorking = false;
                return null;
            }
        }









        /// <summary>
        /// HH: 采用 STSdb FindNext 方式获取连续的多条记录（尚未完全实现，排序分页等）
        /// </summary>
        /// <param name="openId"> 页面中第一个 ID 或者 最后一个 ID </param>
        /// <param name="isNext"> 是否查下一页数据（True 下一页， False 上一页） </param>
        public static List<Account> PageList(List<Func<Account, bool>> predicate, string openId, bool isNext, int inPageSize)
        {
            while (_isWorking == true)
            {
                System.Threading.Thread.Sleep(100);
            }
            _isWorking = true;

            using (var engine = new StorageEngine(Path + SystemFileName, Path + DataFileName))
            {
                _table = engine.OpenXIndex<string, Account>(DataTableName);

                var r = new List<Account> { };
                if (isNext)
                {
                    // 下一页
                    while (inPageSize > 0)
                    {
                        var t = _table.FindNext(openId);
                        if (t != null && t.HasValue)
                        {
                            // 此处可以插入条件判断，如果不符合则不添加直接下一条
                            //foreach (Func<KeyValuePair<long, OPLog>, bool> p in predicate) {
                            //    list = list.Where(p);
                            //}
                            r.Add(t.Value.Value);
                            inPageSize--;
                        }
                        else
                        {
                            // 没有记录跳出
                            inPageSize = 0;
                            break;
                        }

                    }
                }
                else
                {
                    // 上一页
                    while (inPageSize > 0)
                    {
                        var t = _table.FindPrev(openId);
                        if (t != null && t.HasValue)
                        {
                            // 此处可以插入条件判断，如果不符合则不添加直接下一条
                            r.Add(t.Value.Value);
                            inPageSize--;
                        }
                        else
                        {
                            // 没有记录跳出
                            inPageSize = 0;
                            break;
                        }

                    }
                }

                _isWorking = false;
                return r;
            }
        }



    }
}
